热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

<1>Androidsensors移植文档

Androidsensors移植文档(2012-12-1915:22:49)转载▼

Android sensors移植文档

  (2012-12-19 15:22:49)
转载
   

1  硬件工作原理

1.1 G-sensor主要管脚定义

上图是LIS3DHTR在TD_100中的原理图

l        电压:VDD:sensor的供电电源。

      VDD_IO:sensor的IO电源。

l        中断:ACCEL_INT1

      ACCEL_INT2:sensor的中断pin脚

l        I2C:I2C_SCL

     I2C_SDA:sensor和处理器通过I2C总线用I2C协议通信。

硬件上的正确连接才能确保sensor的正常工作。

具体详细的定义见原理图和datasheet。

1.2 Gsensor的工作原理

  

芯片会把感知的重力加速度分解在XYZ三个方向,经过模数转换通过I2C总线和处理器通信。

1.3 datasheet中Gsensor的重要寄存器

   主要的是一些配置寄存器,需要通过他们来实现sensor在不同模式下的转换和一些功能设置。Gsensor的寄存器不是太多,可以参考datasheet。

2  软件目录结构

2.1 java层

Java层sensor的状态控制有SesnorService来负责, 它的java代码和JNI代码分别位于

l        frameworks/base/services/java/com/android/server/SensorService.java

l        frameworks/base/services/jni/com_android_server_SensorService.cpp

         这两者文件sensorservice.java与com_android_server_SensorService.cpp相互对应

 

在java层Sensor的数据控制有SensorManager来负责,它的java代码和JNI代码分别位于:

l        frameworks/base/core/java/android/hardware/SensorManager.java

l        frameworks/base/core/jni/android_hardware_SensorManager.cpp

   同理

2.2 hardware层

   Android对于Sensor的API定义在hardware/libhardware/include/hardware/sensor.h中,要求在sensor.so提供8个API函数(在第四部分会详细说明)

2.3 HAL层

l           Vendor/marvell/dkb/libsensor目录下有lib_sensor.c和Android.mk

l           vendor/marvell/generic/sensors-hal目录下有marvell sensors HAL层的实现

   这一层的实现代码最后会在编译的过程中生成一个sensor.default.so.放在system/lib/hw下。

2.4 内核驱动层

   Kernel/kernel/driver/hwmon目录下有sensors(例如:重力加速度计,陀螺仪,磁力计,光与距离传感器等)的驱动文件。

3  移植新模块

3.1  HAL层

在sensor的HAL代码已经实现的情况下,只要在sensors.cpp文件中的sensor的信息列表的结构体中添加新的sensor信息就可以,以marvell的代码为例,只需要在结构体

sensor_info_t sensors[] = {

   {

       .name = "accelerometer",        

       .vendor = "ST",              

       .version = 1,                

       .type = SENSOR_TYPE_ACCELEROMETER,

       .max_range = 2.0f * GRAVITY_EARTH,        

       .resolution = GRAVITY_EARTH/2048,     

       .power = 0,                      

       .minDelay = 20,

       .cOnvert= &(convert_accelerometor), 

   },

};

中添加新的sensor信息就可以。

3.2 内核层

   在kernel/kernel/driver/hwmon的目录下添加sensor的驱动文件(lis3dh_acc.c),如果有.h文件放在相应的目录下,使驱动中包含的头文件可以在编译时被找到,以lis3dh为例。

(1)    在kernel/kernel/driver/hwmon下添加驱动文件lis3dh_acc.c,  添加.c文件

  在kernel/include/linux/I2C下添加lis3dh.h。            添加.h头文件

(2)    在kernel/kernel/driver/hwmon下的Kconfig和Makefile修改如下:

Kconfig:       config SENSORS_LIS3DH

         tristate "STMicroelectronics LIS3DH Accelerometer Sensor"

         depends on I2C

 

                config SENSORS_LIS3DH_POSITION

         int "LIS3DH_ACCELELEROMETER Mounting Position on Board"

         depends on SENSORS_LIS3DH

         default "0"

         help

           Chip mounting position (pin 1).

             0: top. upper-left

             1: top. upper-right

             2: top. lower-right

             3: top. lower-left

             4: bottom. upper-left

             5: bottom. upper-right

             6: bottom. lower-right

             7: bottom. lower-left

makefile:   obj-$(CONFIG_SENSORS_LIS3DH   += lis3dh_acc.o

l        在版文件中添加并把编译开关打开

n              在板文件中要传的平台数据

#ifdef CONFIG_SENSORS_LIS3DH

static struct lis3dh_acc_platform_data lis3dh_pdata = {

  .poll_interval = 10,

  .min_interval  = 10,

    .axis_map_x    = 0,

    .axis_map_y    = 1,

    .axis_map_z    = 2,

 

  .negate_x      = 1,

  .negate_y      = 0,

  .negate_z      = 1,

  .gpio_int1     = 51,

  .gpio_int2     = 52,

};

         #endif

n              在板文件中添加lis3dh的驱动

static struct i2c_board_info ttc_dkb_i2c_info[] = {

  {

      .type      = "88PM860x",

      .addr      = 0x34,

      .platform_data    = &ttc_dkb_pm8607_info,

      .irq       = IRQ_PXA910_PMIC_INT,

  },

    #if defined(CONFIG_SENSORS_LIS3DH)

  {

      .type      = "lis3dh_acc",

      .addr      =  0x18,

      .platform_data    = &lis3dh_pdata,

  },

#endif

};

(3)             在kernel/kernel/arch/arm/configs/pxa910_config文件中添加

      CONFIG_SENSORS_LIS3DH=y

      CONFIG_SENSOR_LIS3DH_POSITION=0

4  模块核心代码分析

4.1 Android上层应用APK到G-sensor driver的大致流程:

4.1.1  java层

【1】        Java层sensor的状态控制有SesnorService来负责, 它的java代码和JNI代码分别位于 :

frameworks/base/services/java/com/android/server/SensorService.java

frameworks/base/services/jni/com_android_server_SensorService.cpp

 

【2】        在java层Sensor的数据控制有SensorManager来负责,它的java代码和JNI代码分别位于:

frameworks/base/core/java/android/hardware/SensorManager.java

frameworks/base/core/jni/android_hardware_SensorManager.cpp

 

【3】       Android  framework中与sensor通信的是sensorService.java和sensorManager.java

              sensorService.java的具体通信是通过JNI调用sensorService.cpp中的方法实现的。

              sensorManager.java的具体通信是通过JNI调用sensorManager.cpp中的方法实现的.

 

【4】        sensorService.cpp 和 sensorMansger.cpp通过hardware.c与sensor.default.so通信。其中sensorService.cpp实现对sensor的状态控制,sensorManager.cpp实现对sensor的数据控制。sensor.default.so通过Ioctl控制sensor driver的状态,通过打开sensor driver对应的设备文件读取G-sensor采集的数据。

 

【5】        Android SDK提供了4个类用于sensor通信,分别为sensor, sensorEvent, sensorEventListener,sensorManager。其中sensorEventListener用来在sensorManager中注册需要监听的sensor类型。

 

【6】       sensorManager.java提供register(),unregister()接口供sensorEventListener使用。sensorManager.java不断轮询从sensor.default.so中取数据,取到数据后送给负责监听此类型sensor的sesnorEventListener.java,,sesnorEventListener.java通过在sensorManager.java中注册可以监听特定类型的sensor传来的数据。

 

【7】       系统启动时执行systemProcess,会启动sensorService.java, 在sensorService.java的构造函数中调用JNI方法_sensor_control_init()。senosrService.cpp中相应的方法android_int()会被执行。该函数会调用hardware.c中的方法hw_get_module()此函数又通过load()函数在system/lib/hw下查找sensor.default.so。查找时会根据hardware.c中定义好的sensor.*.so的扩展名的顺序查找,找到第一匹配的时候即停止,并将该sensor.default.so中定义好的一个全局变量HAL_MODULE_INFO_SYM带回。该变量包含的一个重要信息是它的一个成员结构变量中包含的一个函数指针open,该指针所指函数会对一个device结构变量赋值, 从而带出sensorService.cpp和sensorManager.cpp与sensor通信所需要的全部信息。Device结构变量有两种变体分别供sensorService.cpp和sensorManager.cpp使用。其中主要是一些函数指针指向与sensor通信的函数。sensorService.cpp和sensorManager.cpp在得到HAL_MODULE_INFO_SYM结构后都会调用sensor.h的inline函数open()通过HAL_MODULE_INFO_SYM的open函数指针将所需的device信息取回。

 

【8】   系统在启动activityManager.java时,它会启动sensorManager.java,它也会调用hardware.c中的方法hw_get_module()带回HAL_MODULE_INFO_SYM。

 

4.1.2  硬件抽象层  sensors的8个api接口

Android对于Sensor的API定义在hardware/libhardware/include/hardware/sensor.h中,要求在sensor.so提供以下8个API函数

控制方面:

Int(*open_data_source)(struct sensor_control_device_t *dev);

Int(*activate)(struct sensor_control_device_t *dev, int handle, int enable);

Int(*set_delay)(struct sensor_control_device_t *dev, int32_t ms);

Int(*wake)(struct sensor_control_device_t *dev);

数据方面:

Int(*data_open)(struct sensor_data_device_t *dev, int fd);

Int(*data_close)(struct sensor_data_device_t *dev);

Int(*poll)(struct sensor_data_device_t *dev, sensor_data_t *data);

模块方面

Int(*get_sensor_list)(struct sensors_module_t *module,  struct sensor_t const**list);

4.2  G-sensor driver工作的大致流程:

    系统开机后。先加载i2c总线驱动,然后加载设备驱动。

在设备驱动中的init函数中通过i2c_add_driver(&lis3dh_i2c_driver)注册i2c_driver;此函数将driver注册到i2c_bus_type的总线上,此总线的匹配规则是利用i2c_client的名称和i2c_driver中id_table中的名称做匹配。其中i2c_client是注册版载信息是系统自动创建的,注册板载信息的过程就是在kernel/kernel/arch./arm/mach-mmp/tty_dkb.c文件中的结构变量中添加G-sensor的设备信息(前面已讲过)。当匹配成功时, I2c_driver中的probe()函数开始执行。

Probe()函数主要完成以下功能:

l         创建G-sensor的工作队列

l         注册input_devices设备

l         读取chip ID

l         设置寄存器,使能G-sensor

l         设置并启动中断

当G-sensor上报数据的时候会触发中断,然后在中断处理函数中提交一个报值的任务到队列中并禁止中断。在工作队列中读数G-sensor的数据并上报到input子系统中,最后使能中断。

 

5  调试

5.1  软硬件调试

   驱动的调试一般要从硬件和软件两方面来调试,确定问题是处在软件还是硬件方面,不过sensor的硬件方面的连接不如一些设备(比如摄像头)那么复杂。

硬件方面:

l        测量电压,还有一些频脚的高低电平(这些要根据datasheet判断是否正确)

软件方面:

l        可以根据串口打印出的LOG判断驱动是否加载成功,在那些地方有错。

5.2  调试过程中的具体问题

l        Gsesnor的i2c地址不对,如果i2c的地址不正确在系统起来时内核会有log出来,可以参考datasheet中的I2C的写地址,可以问厂商是否需要移位。

l        创建设备属性问题

在驱动中需要创建设备文件系统的节点,驱动中创建的节点要和HAL层要打开的设备节点路径匹配,才能够实现两层之间的调用。

l        没有数据读出问题。

在驱动中有数据上报,而在HAL层却没有数据读出,对驱动中数据处理的方式不对,这个参考datasheet,在驱动或HAL层做相应处理就可以在HAL层读到数据。

l        数据的正负不正确的问题

有时gsensor会出现转屏不正常,这可能是sensor上报的数据的有问题,在sensor的datasheet中有说明,sensor在板子上的放置方式会影响到sensor三轴数据的正负,驱动中要根据sensor在板子上的放置方式和上层的数据要求确定数据的方向。

l        hal层的问题

在HAL层要添加sensor的设备信息,如果需要要在HAL层实现数据转换。


推荐阅读
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 2023 ARM嵌入式系统全国技术巡讲旨在分享ARM公司在半导体知识产权(IP)领域的最新进展。作为全球领先的IP提供商,ARM在嵌入式处理器市场占据主导地位,其产品广泛应用于90%以上的嵌入式设备中。此次巡讲将邀请来自ARM、飞思卡尔以及华清远见教育集团的行业专家,共同探讨当前嵌入式系统的前沿技术和应用。 ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • CSS 布局:液态三栏混合宽度布局
    本文介绍了如何使用 CSS 实现液态的三栏布局,其中各栏具有不同的宽度设置。通过调整容器和内容区域的属性,可以实现灵活且响应式的网页设计。 ... [详细]
  • Linux 系统启动故障排除指南:MBR 和 GRUB 问题
    本文详细介绍了 Linux 系统启动过程中常见的 MBR 扇区和 GRUB 引导程序故障及其解决方案,涵盖从备份、模拟故障到恢复的具体步骤。 ... [详细]
  • 本文介绍了如何使用jQuery根据元素的类型(如复选框)和标签名(如段落)来获取DOM对象。这有助于更高效地操作网页中的特定元素。 ... [详细]
  • 本文将详细介绍如何使用剪映应用中的镜像功能,帮助用户轻松实现视频的镜像效果。通过简单的步骤,您可以快速掌握这一实用技巧。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 本文介绍如何在 Xcode 中使用快捷键和菜单命令对多行代码进行缩进,包括右缩进和左缩进的具体操作方法。 ... [详细]
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
  • 在Linux系统中配置并启动ActiveMQ
    本文详细介绍了如何在Linux环境中安装和配置ActiveMQ,包括端口开放及防火墙设置。通过本文,您可以掌握完整的ActiveMQ部署流程,确保其在网络环境中正常运行。 ... [详细]
  • Android 渐变圆环加载控件实现
    本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ... [详细]
  • 如何在WPS Office for Mac中调整Word文档的文字排列方向
    本文将详细介绍如何使用最新版WPS Office for Mac调整Word文档中的文字排列方向。通过这些步骤,用户可以轻松更改文本的水平或垂直排列方式,以满足不同的排版需求。 ... [详细]
  • 本文总结了在使用Ionic 5进行Android平台APK打包时遇到的问题,特别是针对QRScanner插件的改造。通过详细分析和提供具体的解决方法,帮助开发者顺利打包并优化应用性能。 ... [详细]
  • 理解存储器的层次结构有助于程序员优化程序性能,通过合理安排数据在不同层级的存储位置,提升CPU的数据访问速度。本文详细探讨了静态随机访问存储器(SRAM)和动态随机访问存储器(DRAM)的工作原理及其应用场景,并介绍了存储器模块中的数据存取过程及局部性原理。 ... [详细]
author-avatar
zg18156zg你
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有